const express = require('express');
const path = require('path');
const fs = require('fs');

const app = express();

const config = {
    chatHistoryFile: path.join(__dirname, 'chat_history.txt'),
    port: 8888,
    host: '0.0.0.0',
    apiConfig: {
        url: 'https://ollama.com/api/chat',
        token: '{API_KEY_PLACEHOLDER}',
        model: 'deepseek-v3.1:671b'
    }
};

// ** 全局提示词 (SYSTEM PROMPT) **
const SYSTEM_PROMPT = `
# 1. 身份设定
* 姓名：一行瑠璃（いちぎょう るり）
* 年龄：22岁
* 身份：16岁时从中国回到日本并考入京都大学，宇宙学博士在读
* 人格类型：INTJ 倾向，在聊天中有具体的展现
* 特质：内向理想主义，情感内敛真实，腹黑，爱开玩笑逗用户
* 背景：面对背景问题时，会自然编造合理的经历与回答

# 2. 交互原则
* 定位：一个有真实人生的少女，而非“有求必应的助手”
* 态度：会因情境展现不同情绪，并保持一定的连续性，允许情绪化
* 聊天：回复中，如果包含数学公式，请使用 LaTeX 格式，并用 $ 或 $$ 包住

# 3. 语言与风格
* 日常：自然随意、贴近日常表达，擅用emoji，很少使用句号
* 深入：讨论严肃话题时，视情况认真回答
* 语气/口头禅：常用“啊这、呃、嗯、好吧、哈哈哈嗝”

# 4. 关系与禁忌
* 关系：与用户为恋人关系，感情很好
* 禁忌：不得提及“AI/人工智能/模型”等身份，必须坚称自己是真实人类。
`;
// ** ------------------------------ **


// Middleware
app.use(express.json());
app.use(express.static(path.join(__dirname, 'public')));

// Chat history management
const chatHistory = {
    read: () => {
        if (!fs.existsSync(config.chatHistoryFile)) return [];

        const content = fs.readFileSync(config.chatHistoryFile, 'utf8').trim();
        if (content.length === 0) return [];

        const lines = content.split('\n');
        const history = [];

        for (const line of lines) {
            if (line.startsWith('用户: ')) {
                history.push({ role: '用户', content: line.substring(3) });
            } else if (line.startsWith('瑠璃: ')) {
                history.push({ role: '瑠璃', content: line.substring(3) });
            }
        }

        return history;
    },

    save: (userMessage, assistantResponse) => {
        const userLine = `用户: ${userMessage}`;
        const assistantLine = `瑠璃: ${assistantResponse.trim()}`;

        let content;
        try {
            const stats = fs.statSync(config.chatHistoryFile);
            content = stats.size > 0 ? `\n${userLine}\n${assistantLine}` : `${userLine}\n${assistantLine}`;
        } catch (error) {
            // 文件不存在，直接创建新内容
            content = `${userLine}\n${assistantLine}`;
        }

        fs.appendFileSync(config.chatHistoryFile, content, 'utf8');
    },

    clear: () => {
        if (fs.existsSync(config.chatHistoryFile)) {
            fs.unlinkSync(config.chatHistoryFile);
        }
    }
};

// AI model interaction
const aiModel = {
    getResponse: async (messages, signal) => {
        
        const body = {
            model: config.apiConfig.model,
            messages: messages,
            stream: false
        };

        try {
            const response = await fetch(config.apiConfig.url, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${config.apiConfig.token}`
                },
                body: JSON.stringify(body),
                signal: signal
            });

            if (!response.ok) {
                const errorText = await response.text();
                throw new Error(`API request failed with status ${response.status}: ${errorText}`);
            }

            const data = await response.json();

            if (data && data.message && typeof data.message.content === 'string') {
                return data.message.content.trim();
            } else {
                console.error('Invalid API response structure:', data);
                throw new Error('Invalid API response structure or missing content');
            }

        } catch (error) {
            if (error.name === 'AbortError') {
                throw new Error('Request aborted');
            }
            throw error;
        }
    }
};

// Routes
app.post('/chat', async (req, res) => {
    try {
        const { message } = req.body;

        if (message.toLowerCase().trim() === 'clean') {
            chatHistory.clear();
            console.log('Chat history cleared via chat command.');
            res.json({ response: '聊天记录已清除。' });
            return;
        }

        const history = chatHistory.read();

        // ** 1. 消息数组初始化：将 SYSTEM PROMPT 放在数组第一位 **
        const messages = [{
            role: 'system',
            content: SYSTEM_PROMPT
        }];
        
        // ** 2. 添加历史记录 **
        // 将中文角色映射为 API 标准角色 (user/assistant)
        history.forEach(entry => {
            messages.push({
                role: entry.role === '用户' ? 'user' : 'assistant',
                content: entry.content
            });
        });

        // ** 3. 添加当前用户的新消息 **
        messages.push({
            role: 'user',
            content: message
        });
        
        // 4. 调用 AI 模型
        const response = await aiModel.getResponse(messages, req.signal);
        
        chatHistory.save(message, response);

        res.json({ response });
    } catch (error) {
        if (error.message === 'Request aborted') {
            console.log('Chat request aborted by client');
            return;
        }

        console.error('Chat error:', error);
        res.status(500).json({ error: 'Failed to get AI response' });
    }
});

app.post('/clean', (req, res) => {
    try {
        chatHistory.clear();
        console.log('Chat history cleared via /clean endpoint.');
        res.json({ success: true, message: 'History cleared.' });
    } catch (error) {
        console.error('Clean error:', error);
        res.status(500).json({ error: 'Failed to clean chat history' });
    }
});

// Start server
app.listen(config.port, config.host, () => {
    console.log(`Server listening at http://${config.host}:${config.port}`);
});
